package com.zjcloud.jwgl.controller;

import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.zjcloud.common.annotation.Log;
import com.zjcloud.common.core.controller.BaseController;
import com.zjcloud.common.core.domain.AjaxResult;
import com.zjcloud.common.enums.BusinessType;
import com.zjcloud.jwgl.domain.AcScheduleAlgorithmConfig;
import com.zjcloud.jwgl.service.IAcScheduleAlgorithmConfigService;
import com.zjcloud.common.utils.poi.ExcelUtil;
import com.zjcloud.common.core.page.TableDataInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 排课算法配置Controller
 * 
 * @author zjcloud
 * @date 2024-12-19
 */
@RestController
@RequestMapping("/jwgl/schedule/algorithm")
public class AcScheduleAlgorithmConfigController extends BaseController
{
    private static final Logger log = LoggerFactory.getLogger(AcScheduleAlgorithmConfigController.class);

    @Autowired
    private IAcScheduleAlgorithmConfigService acScheduleAlgorithmConfigService;

    /**
     * 查询排课算法配置列表
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:list')")
    @GetMapping("/list")
    public TableDataInfo list(AcScheduleAlgorithmConfig acScheduleAlgorithmConfig)
    {
        startPage();
        List<AcScheduleAlgorithmConfig> list = acScheduleAlgorithmConfigService.selectAcScheduleAlgorithmConfigList(acScheduleAlgorithmConfig);
        return getDataTable(list);
    }

    /**
     * 导出排课算法配置列表
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:export')")
    @Log(title = "排课算法配置", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, AcScheduleAlgorithmConfig acScheduleAlgorithmConfig)
    {
        List<AcScheduleAlgorithmConfig> list = acScheduleAlgorithmConfigService.selectAcScheduleAlgorithmConfigList(acScheduleAlgorithmConfig);
        ExcelUtil<AcScheduleAlgorithmConfig> util = new ExcelUtil<AcScheduleAlgorithmConfig>(AcScheduleAlgorithmConfig.class);
        util.exportExcel(response, list, "排课算法配置数据");
    }

    /**
     * 获取排课算法配置详细信息
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:query')")
    @GetMapping(value = "/{configId}")
    public AjaxResult getInfo(@PathVariable("configId") Long configId)
    {
        return success(acScheduleAlgorithmConfigService.selectAcScheduleAlgorithmConfigById(configId));
    }

    /**
     * 新增排课算法配置
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:add')")
    @Log(title = "排课算法配置", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody AcScheduleAlgorithmConfig acScheduleAlgorithmConfig)
    {
        // 验证配置参数
        Map<String, Object> validateResult = acScheduleAlgorithmConfigService.validateConfig(acScheduleAlgorithmConfig);
        if (!(Boolean) validateResult.get("isValid")) {
            return error(validateResult.get("errorMsg").toString());
        }
        
        return toAjax(acScheduleAlgorithmConfigService.insertAcScheduleAlgorithmConfig(acScheduleAlgorithmConfig));
    }

    /**
     * 修改排课算法配置
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:edit')")
    @Log(title = "排课算法配置", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody AcScheduleAlgorithmConfig acScheduleAlgorithmConfig)
    {
        // 验证配置参数
        Map<String, Object> validateResult = acScheduleAlgorithmConfigService.validateConfig(acScheduleAlgorithmConfig);
        if (!(Boolean) validateResult.get("isValid")) {
            return error(validateResult.get("errorMsg").toString());
        }
        
        return toAjax(acScheduleAlgorithmConfigService.updateAcScheduleAlgorithmConfig(acScheduleAlgorithmConfig));
    }

    /**
     * 删除排课算法配置
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:remove')")
    @Log(title = "排课算法配置", businessType = BusinessType.DELETE)
    @DeleteMapping("/{configIds}")
    public AjaxResult remove(@PathVariable Long[] configIds)
    {
        return toAjax(acScheduleAlgorithmConfigService.deleteAcScheduleAlgorithmConfigByIds(configIds));
    }

    /**
     * 获取默认算法配置
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:query')")
    @GetMapping("/default")
    public AjaxResult getDefaultConfig()
    {
        AcScheduleAlgorithmConfig defaultConfig = acScheduleAlgorithmConfigService.selectDefaultConfig();
        return success(defaultConfig);
    }

    /**
     * 设置默认配置
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:edit')")
    @Log(title = "设置默认算法配置", businessType = BusinessType.UPDATE)
    @PostMapping("/setDefault/{configId}")
    public AjaxResult setDefaultConfig(@PathVariable Long configId, @RequestParam(required = false, defaultValue = "1") Integer isDefault)
    {
        try {
            boolean result = acScheduleAlgorithmConfigService.setDefaultConfig(configId, isDefault == 1);
            
            if (result) {
                String message = isDefault == 1 ? "设置默认配置成功" : "取消默认配置成功";
                return success(message);
            } else {
                String message = isDefault == 1 ? "设置默认配置失败" : "取消默认配置失败";
                return error(message);
            }
        } catch (Exception e) {
            log.error("操作默认配置失败，配置ID: {}, 操作: {}, 错误: {}", configId, isDefault == 1 ? "设置" : "取消", e.getMessage(), e);
            return error("操作默认配置失败: " + e.getMessage());
        }
    }

    /**
     * 根据算法类型查询配置列表
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:query')")
    @GetMapping("/type/{algorithmType}")
    public AjaxResult getConfigsByType(@PathVariable String algorithmType)
    {
        List<AcScheduleAlgorithmConfig> configs = acScheduleAlgorithmConfigService.selectConfigsByAlgorithmType(algorithmType);
        return success(configs);
    }

    /**
     * 根据配置名称查询配置
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:query')")
    @GetMapping("/name/{configName}")
    public AjaxResult getConfigByName(@PathVariable String configName)
    {
        AcScheduleAlgorithmConfig config = acScheduleAlgorithmConfigService.selectConfigByName(configName);
        return success(config);
    }

    /**
     * 查询启用的配置列表
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:query')")
    @GetMapping("/enabled")
    public AjaxResult getEnabledConfigs()
    {
        List<AcScheduleAlgorithmConfig> configs = acScheduleAlgorithmConfigService.selectEnabledConfigs();
        return success(configs);
    }

    /**
     * 复制配置
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:add')")
    @Log(title = "复制算法配置", businessType = BusinessType.INSERT)
    @PostMapping("/copy/{configId}")
    public AjaxResult copyConfig(@PathVariable Long configId, @RequestParam String newConfigName)
    {
        try {
            // 验证新配置名称
            if (newConfigName == null || newConfigName.trim().isEmpty()) {
                return error("配置名称不能为空");
            }
            
            if (newConfigName.length() < 2 || newConfigName.length() > 100) {
                return error("配置名称长度必须在2-100个字符之间");
            }
            
            // 检查新配置名称是否已存在
            AcScheduleAlgorithmConfig existingConfig = acScheduleAlgorithmConfigService.selectConfigByName(newConfigName.trim());
            if (existingConfig != null) {
                return error("配置名称已存在");
            }
            
            Long newConfigId = acScheduleAlgorithmConfigService.copyConfig(configId, newConfigName.trim());
            if (newConfigId != null) {
                return success("复制配置成功，新配置ID: " + newConfigId);
            } else {
                return error("复制配置失败");
            }
        } catch (Exception e) {
            log.error("复制配置失败，源配置ID: {}, 新配置名称: {}, 错误: {}", configId, newConfigName, e.getMessage(), e);
            return error("复制配置失败: " + e.getMessage());
        }
    }

    /**
     * 获取推荐配置
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:query')")
    @GetMapping("/recommend")
    public AjaxResult getRecommendedConfig(
            @RequestParam String algorithmType,
            @RequestParam(required = false) Integer courseCount,
            @RequestParam(required = false) Integer classroomCount)
    {
        try {
            AcScheduleAlgorithmConfig recommendedConfig = acScheduleAlgorithmConfigService.getRecommendedConfig(
                    algorithmType, courseCount, classroomCount);
            if (recommendedConfig != null) {
                return success(recommendedConfig);
            } else {
                return error("未找到推荐配置");
            }
        } catch (Exception e) {
            log.error("获取推荐配置失败，算法类型: {}, 错误: {}", algorithmType, e.getMessage(), e);
            return error("获取推荐配置失败: " + e.getMessage());
        }
    }

    /**
     * 验证配置参数
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:query')")
    @PostMapping("/validate")
    public AjaxResult validateConfig(@RequestBody AcScheduleAlgorithmConfig config)
    {
        Map<String, Object> validateResult = acScheduleAlgorithmConfigService.validateConfig(config);
        return success(validateResult);
    }

    /**
     * 获取算法类型列表
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:query')")
    @GetMapping("/types")
    public AjaxResult getAlgorithmTypes()
    {
        try {
            // 返回支持的算法类型
            java.util.List<java.util.Map<String, Object>> types = new java.util.ArrayList<>();
            java.util.Map<String, Object> genetic = new java.util.HashMap<>();
            genetic.put("code", "GENETIC");
            genetic.put("name", "遗传算法");
            genetic.put("description", "基于遗传算法的智能排课");
            types.add(genetic);
            
            java.util.Map<String, Object> simulated = new java.util.HashMap<>();
            simulated.put("code", "SIMULATED_ANNEALING");
            simulated.put("name", "模拟退火算法");
            simulated.put("description", "基于模拟退火算法的智能排课");
            types.add(simulated);
            
            java.util.Map<String, Object> tabu = new java.util.HashMap<>();
            tabu.put("code", "TABU_SEARCH");
            tabu.put("name", "禁忌搜索算法");
            tabu.put("description", "基于禁忌搜索算法的智能排课");
            types.add(tabu);
            
            return success(types);
        } catch (Exception e) {
            log.error("获取算法类型列表失败: {}", e.getMessage(), e);
            return error("获取算法类型列表失败: " + e.getMessage());
        }
    }

    /**
     * 测试配置性能
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:test')")
    @Log(title = "测试算法配置性能", businessType = BusinessType.OTHER)
    @PostMapping("/test/{configId}")
    public AjaxResult testConfig(@PathVariable Long configId, @RequestBody Map<String, Object> testParams)
    {
        try {
            // 这里应该实现具体的性能测试逻辑
            // 暂时返回模拟数据
            Map<String, Object> testResult = new java.util.HashMap<>();
            testResult.put("configId", configId);
            testResult.put("testTime", new java.util.Date());
            testResult.put("executionTime", 1500); // 毫秒
            testResult.put("successRate", 0.95);
            testResult.put("score", 85.5);
            testResult.put("status", "测试完成");
            
            return success(testResult);
        } catch (Exception e) {
            log.error("测试配置性能失败，配置ID: {}, 错误: {}", configId, e.getMessage(), e);
            return error("测试配置性能失败: " + e.getMessage());
        }
    }

    /**
     * 重置配置为默认值
     */
    @PreAuthorize("@ss.hasPermi('jwgl:schedule:algorithm:edit')")
    @Log(title = "重置算法配置", businessType = BusinessType.UPDATE)
    @PostMapping("/reset/{configId}")
    public AjaxResult resetConfig(@PathVariable Long configId)
    {
        try {
            AcScheduleAlgorithmConfig config = acScheduleAlgorithmConfigService.selectAcScheduleAlgorithmConfigById(configId);
            if (config == null) {
                return error("配置不存在");
            }
            
            // 重置为默认值
            config.setPopulationSize(100);
            config.setMaxGenerations(1000);
            config.setCrossoverRate(0.8);
            config.setMutationRate(0.1);
            config.setEliteRate(0.1);
            config.setConvergenceThreshold(0.001);
            
            int result = acScheduleAlgorithmConfigService.updateAcScheduleAlgorithmConfig(config);
            if (result > 0) {
                return success("重置配置成功");
            } else {
                return error("重置配置失败");
            }
        } catch (Exception e) {
            log.error("重置配置失败，配置ID: {}, 错误: {}", configId, e.getMessage(), e);
            return error("重置配置失败: " + e.getMessage());
        }
    }
}